import [Scope,Value,BuiltIn,Number,vList,Symbol,Function,LispParser]
import structs/ArrayList
import io/[FileReader,File]

scope := Scope new()

interactive? := false
f? := false
//Currently 1835 lines of code, more to come =D // TODO: write more of the sdk, currently only 3 files :P And add auto-load files from the sdk folder
main : func(args : ArrayList<String>) -> Int {
    "Little Lisp version .3 command line interface." println()
    filepath : String
    for(arg in args) {
        if(arg == "-i") {
            interactive? = true
            "Interactive mode selected. Use the (exit) command to quit the interpreter at any time.\n\n" println()
        }
        else if(arg == "-f") {
            f? = true
        }
        else if(f?) {
            filepath = arg
            ("File " + arg + " selected. Interpreter will stop after the file has been executed.\n\n") println()
        }
        else if(args indexOf(arg) != 0) {
            ("Unrecognized option " + arg) println()
            return 0
        }
    }
    
    if(interactive?) { "Loading sdk files..." println() }
	root := File new(args[0]) parent()
    sdk := root getChild("sdk")
    if(!sdk exists?() || !sdk dir?()) {
        if(interactive?) { "Folder sdk was not found. Continuing without it.\n\n" println() }
    } else {
        includes := sdk getChildren()
        for(inc in includes) {
            if(inc file?()) {
                f := FileReader new(inc getPath())
                data := ""
                while(f hasNext?()) {
                    data += f read()
                }
                parser := LispParser new(data)
                values := parser work()
                
                for(val in values) {
                    val evaluate(scope)
                }
            }
        }
        if(interactive?) { "sdk files loaded.\n\n" println() }
    }
    
    loop(filepath)
}

loop : func(path : String) {
    if(interactive?) {
        while(stdin hasNext?()) {
            ">> " print()
            parser := LispParser new(stdin readLine())
            values := parser work()
            for(val in values) {
                ("=> "+val evaluate(scope) toString()) println()
            }
        }
    } else if(f?) {
        if(File new(path) exists?()) {
            f := FileReader new(path)
            data := ""
            while(f hasNext?()) {
                data += f read()
            }
            parser := LispParser new(data)
            values := parser work()
            
            for(val in values) {
                val evaluate(scope) toString() println()
            }
        } else {
            ("File " + path + " not found. Exiting now.\n\n") println()
        }
    } else {
        "No recognized mode selected. Exiting now.\n\n" println()
    }
}
